// promise 在解决异步编程问题（嵌套的方式） 采用了链式调用来解决的 （回调）  复杂的业务逻辑还是有嵌套问题
// es6 生成器（特殊）函数， 让异步编程变的更像同步
// generator函数是有暂停功能的， 可以按照自己的需要继续执行， 按照顺序执行异步流程
/*
function* gen() {
  let a1 = yield "sleep"; // 代码执行的时候碰到yield 就结束了
  console.log(a1);
  let a2 = yield "eat";
  console.log(a2);
  //   return undefined
}
let it = gen();
// 生成器函数 生成的是迭代器 （对象，具备一个方法 next 返回本次迭代的值）
console.log(it.next()); // 默认调用genernator 函数 会返回本次的结果， 是否函数执行完毕
console.log(it.next("a1"));
console.log(it.next("a2"));
*/
// yield 返回值问题, 每次调用next 函数的时候 会给上一次的yield赋值

let likeArray = {
  0: 1,
  1: 2,
  2: 3,
  length: 3, // 数组内部实现了迭代的方法，我们可以自己去元编程
  [Symbol.iterator]: function* () {
    let idx = 0;
    let len = this.length;
    while (idx !== len) {
      yield this[idx++];
    }
  },

  //   [Symbol.iterator]() {
  //     let idx = 0;
  //     return {
  //       next: () => {
  //         return { value: this[idx], done: idx++ === this.length };
  //       },
  //     };
  //   },
};

// 类数组（索引和长度之外） 能迭代

// console.log([...likeArray]); // 不停的调用next方法直到返回的对象的done属性为true

let fs = require("fs").promises;
function* read() {
  try {
    // 这个代码肯定是异步的，但是写的像同步代码
    let url = yield fs.readFile("./fileUrl1.txt", "utf8");
    let name = yield fs.readFile(url, "utf8");
    return name;
  } catch (e) {
    console.log(e, 55);
  }
}
/*
let it = read();
let { value, done } = it.next();
if (!done) {
  value.then((data) => {
    let { value, done } = it.next(data);
    if (!done) {
      value.then((data) => {
        let { value, done } = it.next(data);
        console.log(value, done);
      });
    }
  });
}
*/
function co(it) {
  // 串行执行，基于回调
  return new Promise((resolve, reject) => {
    function next(data) {
      let { value, done } = it.next(data);
      if (!done) {
        Promise.resolve(value).then(
          (data) => {
            next(data);
          },
          (err) => {
            it.throw(err);
          }
        );
      } else {
        resolve(value);
      }
    }
    next();
  });
}
co(read()).then((data) => {
  console.log(data);
});

// function* gen() {
//   try {
//     yield "sleep";
//     yield "eat";
//   } catch (e) {
//     console.log(e);
//   }
// }
// let it = gen();
// console.log(it.next());
// console.log(it.throw("我认为出错了"));

// generator 是什么东西？ 能干什么， 如何解决异步编程问题的。
